home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / haeberli / libgutil / sprender.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  16KB  |  799 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  *    sprender -
  19.  *        Generic gl rendering stuff.
  20.  *
  21.  *                Paul Haeberli - 1990
  22.  */
  23. #include "stdio.h"
  24. #include "gl.h"
  25. #include "math.h"
  26. #include "vect.h"
  27. #include "render.h"
  28. #include "acc.h"
  29. #include "sgiobj.h"
  30. #include "trilist.h"
  31.  
  32. static objidcolor();
  33.  
  34. #define ACCSCALE    (0.25)
  35.  
  36. typedef struct rendobj {
  37.     struct rendobj *next;
  38.     sgiobj *obj;
  39.     float matrix[4][4];
  40.     int isdiff, isspec, istrans;
  41.     vect diffc, specc, transc;
  42.     int diffmap, specmap;
  43. } rendobj;
  44.  
  45. static rendobj *orendlist;
  46. static rendobj curshader;
  47. static rendobj *trendlist;
  48. static int renderq = RQ_SHADED;
  49. static int demo, firsted;
  50. static int doclear = 1;
  51. static char backimagename[256];
  52.  
  53. demomode(m)
  54. int m;
  55. {
  56.     demo = m;
  57.     if(demo) {
  58.     singlebuffer();
  59.     gconfig();
  60.     } else {
  61.     doublebuffer();
  62.     gconfig();
  63.     }
  64. }
  65.  
  66. renderquality(q)
  67. int q;
  68. {
  69.     renderq = q;
  70. }
  71.  
  72. getrenderquality()
  73. {
  74.     return renderq;
  75. }
  76.  
  77. backimage(name)
  78. char *name;
  79. {
  80.     strcpy(backimagename,name);
  81. }
  82.  
  83. renderclear(f)
  84. {
  85.     doclear = f;
  86. }
  87.  
  88. static clearscreen(how)
  89. int how;
  90. {
  91.     blendfunction(BF_ONE,BF_ZERO);
  92.     zwritemask(0x00ffffff);
  93.     zclear();
  94.     zbuffer(0);
  95.     settexture(0);
  96.     switch(renderq) {
  97.     case RQ_LINES:
  98.         cpack(0x00ffffff);
  99.         clear();
  100.         break;
  101.     case RQ_NORMALS:
  102.         cpack(0x00808080);
  103.         clear();
  104.         break;
  105.     default:
  106.         if(strlen(backimagename)>0) {
  107.         drawback(backimagename);
  108.         } else  {
  109.         cpack(0x00ffffff);
  110.         clear();
  111.         }
  112.         break;
  113.     }
  114. }
  115.  
  116. rendershader(diffmap,diffc,specmap,specc,transc)
  117. int diffmap;
  118. vect *diffc;
  119. int specmap;
  120. vect *specc;
  121. vect *transc;
  122. {
  123.     float minval;
  124.  
  125.     minval = 0.5/255.0;
  126.     curshader.diffmap = diffmap;
  127.     if(diffc) {
  128.     curshader.diffc = *diffc;
  129.     if(diffc->x>minval || diffc->y>minval || diffc->z>minval)
  130.         curshader.isdiff = 1;
  131.     else
  132.         curshader.isdiff = 0;
  133.     } else {
  134. #ifdef OLDWAY
  135.     vone(&curshader.diffc);
  136.     curshader.isdiff = 1;
  137. #else
  138.     vzero(&curshader.diffc);
  139.     curshader.isdiff = 0;
  140. #endif
  141.     }
  142.  
  143.     curshader.specmap = specmap;
  144.     if(specc) {
  145.     curshader.specc = *specc;
  146.         if(specc->x>minval || specc->y>minval || specc->z>minval)
  147.         curshader.isspec = 1;
  148.     else
  149.         curshader.isspec = 0;
  150.     } else {
  151.     vone(&curshader.specc);
  152.     curshader.isspec = 1;
  153.     }
  154.  
  155.     if(transc && (transc->x>minval || transc->y>minval || transc->z>minval)) {
  156.     curshader.transc = *transc;
  157.     curshader.istrans = 1;
  158.     } else {
  159.     vzero(&curshader.transc);
  160.     curshader.istrans = 0;
  161.     }
  162. }
  163.  
  164. printshader()
  165. {
  166.     printf("isdiff: %d ",curshader.isdiff);
  167.     vprint(&curshader.diffc);
  168.     printf("isspec: %d ",curshader.isspec);
  169.     vprint(&curshader.specc);
  170.     printf("istrans: %d ",curshader.istrans);
  171.     vprint(&curshader.transc);
  172.     printf("diffmap %d, specmap %d\n",curshader.diffmap,curshader.specmap);
  173. }
  174.  
  175. renderobj(obj)
  176. sgiobj *obj;
  177. {
  178.     rendobj *robj;
  179.  
  180.     robj = (rendobj *)mymalloc(sizeof(rendobj));
  181.     robj->obj = obj;
  182.     getmatrix(robj->matrix);
  183.  
  184.     robj->isdiff = curshader.isdiff;
  185.     robj->isspec = curshader.isspec;
  186.     robj->istrans = curshader.istrans;
  187.     robj->diffc = curshader.diffc;
  188.     robj->specc = curshader.specc;
  189.     robj->transc = curshader.transc;
  190.     robj->diffmap = curshader.diffmap;
  191.     robj->specmap = curshader.specmap;
  192.  
  193.     if(robj->istrans) {
  194.         robj->next = trendlist;
  195.         trendlist = robj;
  196.     } else {
  197.         robj->next = orendlist;
  198.         orendlist = robj;
  199.     }
  200. }
  201.  
  202. beginrender()
  203. {
  204.     rendobj *nobj;
  205.  
  206.     if(!firsted) {
  207.     materialname("/usr/people/paul/gfx/render.mat");
  208.     lightsname("/usr/people/paul/gfx/render.lgt");
  209.     shadingoff();
  210.     firsted = 1;
  211.     }
  212.     while(orendlist) {
  213.     nobj = orendlist->next;
  214.     free(orendlist);
  215.     orendlist = nobj;
  216.     }
  217.     while(trendlist) {
  218.     nobj = trendlist->next;
  219.     free(trendlist);
  220.     trendlist = nobj;
  221.     }
  222.     pushmatrix();
  223. }
  224.  
  225. endrender()
  226. {
  227.     rendobj *robj;
  228.     int objid;
  229.     unsigned long tr, tg, tb, c;
  230.     unsigned long rr, rg, rb;
  231.     int dospec, dodiff;
  232.     vect v, vdif, vspec;
  233.     float projmat[4][4], psmat[4][4];
  234.     
  235.     if(doclear) 
  236.     clearscreen(renderq);
  237.     popmatrix();
  238.  
  239.     if(demo)
  240.     sleep(1);
  241.     pushmatrix();
  242.     switch(renderq) {
  243.     case RQ_NORMALS:
  244.         zbuffer(1);
  245.         zwritemask(0x00ffffff);
  246.         backface(1);
  247.         blendfunction(BF_ONE,BF_ZERO);
  248.         settexture(0);
  249.  
  250.         robj = orendlist;
  251.         while(robj) {
  252.         loadmatrix(robj->matrix);
  253.         drawnormobj(robj->obj,robj->matrix);
  254.         robj = robj->next;
  255.         }
  256.         robj = trendlist;
  257.         while(robj) {
  258.         loadmatrix(robj->matrix);
  259.         drawnormobj(robj->obj,robj->matrix);
  260.         robj = robj->next;
  261.         }
  262.         break;
  263.  
  264.     case RQ_PSOUT:
  265.         pspolyrender(); 
  266.         break;
  267.  
  268.     case RQ_OBJID:
  269.         zbuffer(1);
  270.         zwritemask(0x00ffffff);
  271.         backface(1);
  272.         blendfunction(BF_ONE,BF_ZERO);
  273.         settexture(0);
  274.  
  275.         objid = 0;
  276.         robj = orendlist;
  277.         while(robj) {
  278.         objidcolor(objid++);
  279.         loadmatrix(robj->matrix);
  280.         drawsgiobj(robj->obj,DRAW_POINTS);
  281.         robj = robj->next;
  282.         }
  283.         robj = trendlist;
  284.         while(robj) {
  285.         objidcolor(objid++);
  286.         loadmatrix(robj->matrix);
  287.         drawsgiobj(robj->obj,DRAW_POINTS);
  288.         robj = robj->next;
  289.         }
  290.         break;
  291.  
  292.     case RQ_LINES:
  293.         switch(gfxmachine()) {
  294.         MACH4DVGX:
  295.             linesmooth(SML_ON|SML_SMOOTHER|SML_END_CORRECT);
  296.             blendfunction(BF_SA,BF_MSA);
  297.             break;
  298.         default:
  299.             linesmooth(SML_OFF);
  300.             blendfunction(BF_ONE,BF_ZERO);
  301.             break;
  302.         }
  303.         zbuffer(1);
  304.         zwritemask(0x00000000);
  305.         backface(0);
  306.         cpack(0x80000000);
  307.         settexture(0);
  308.  
  309.         robj = orendlist;
  310.         while(robj) {
  311.         loadmatrix(robj->matrix);
  312.         drawsgiobj(robj->obj,DRAW_LINES);
  313.         robj = robj->next;
  314.         }
  315.         robj = trendlist;
  316.         while(robj) {
  317.         loadmatrix(robj->matrix);
  318.         drawsgiobj(robj->obj,DRAW_LINES);
  319.         robj = robj->next;
  320.         }
  321.         linesmooth(SML_OFF);
  322.         break;
  323.  
  324.     case RQ_GLSHADED:
  325.         zbuffer(1);
  326.         zwritemask(0x00ffffff);
  327.         backface(1);
  328.         blendfunction(BF_ONE,BF_ZERO);
  329.         settexture(0);
  330.         shadingon();
  331.  
  332.         robj = orendlist;
  333.         while(robj) {
  334.         lmcolor(LMC_SPECULAR);
  335.         c3f((float*)&robj->specc);
  336.         lmcolor(LMC_DIFFUSE);
  337.         if(robj->diffmap) {
  338.             textureaverage(robj->diffmap,&vdif);
  339.             vmult(&robj->diffc,&vdif,&vdif);
  340.             c3f((float*)&vdif);
  341.         } else {
  342.             c3f((float*)&robj->diffc);
  343.         }
  344.         loadmatrix(robj->matrix);
  345.         drawsgiobj(robj->obj,DRAW_POINTS|DRAW_NORMALS);
  346.         robj = robj->next;
  347.         }
  348.  
  349.         zwritemask(0x00000000);
  350.         backface(0);            
  351.         blendfunction(BF_ONE,BF_ONE);
  352.  
  353.         vzero(&vdif);
  354.         robj = trendlist;
  355.         while(robj) {
  356.             lmcolor(LMC_DIFFUSE);
  357.             c3f((float*)&vdif);
  358.         lmcolor(LMC_SPECULAR);
  359.         vspec = robj->specc;
  360.         c3f((float*)&vspec);
  361.         loadmatrix(robj->matrix);
  362.         drawsgiobj(robj->obj,DRAW_POINTS|DRAW_NORMALS);
  363.         robj = robj->next;
  364.         }
  365.         lmcolor(LMC_COLOR);
  366.         shadingoff();
  367.         break;
  368.      
  369.     case RQ_SHADED:
  370.         zbuffer(1);
  371.         zwritemask(0x00ffffff);
  372.         backface(1);
  373.         settexture(0);
  374.  
  375.         robj = orendlist;
  376.         while(robj) {
  377.         if(robj->isspec && robj->specmap) 
  378.             dospec = 1;
  379.         else
  380.             dospec = 0;
  381.         if(robj->isdiff) 
  382.             dodiff = 1;
  383.         else
  384.             dodiff = 0;
  385.         if(dodiff) {
  386.             blendfunction(BF_ONE,BF_ZERO);
  387.             shadingon();
  388.             lmcolor(LMC_DIFFUSE);
  389.             tmc3f((float*)&robj->diffc);
  390.             settexture(robj->diffmap);
  391.             loadmatrix(robj->matrix);
  392.             if(robj->diffmap) 
  393.             drawsgiobj(robj->obj,DRAW_POINTS|DRAW_NORMALS|DRAW_UVS);
  394.             else 
  395.             drawsgiobj(robj->obj,DRAW_POINTS|DRAW_NORMALS);
  396.             lmcolor(LMC_COLOR);
  397.             shadingoff();
  398.         }
  399.         if(dospec) {
  400.             if(dodiff) 
  401.             blendfunction(BF_ONE,BF_ONE);
  402.             else
  403.             blendfunction(BF_ONE,BF_ZERO);
  404.             tmc3f((float*)&robj->specc);
  405.             settexture(robj->specmap);
  406.             loadmatrix(robj->matrix);
  407.             drawenvobj(robj->obj,robj->matrix);
  408.         }
  409.         robj = robj->next;
  410.         }
  411.         if(demo)
  412.         sleep(1);
  413.  
  414.         zwritemask(0x00000000);     /* draw specular */
  415.         backface(0);            
  416.         blendfunction(BF_ONE,BF_ONE);
  417.  
  418.         robj = trendlist;
  419.         while(robj) {
  420.         if(robj->isspec && robj->specmap) {
  421.             v = robj->specc;
  422.             if(vsignif(&v)) {
  423.             tmc3f((float*)&v);
  424.             settexture(robj->specmap);
  425.             loadmatrix(robj->matrix);
  426.             drawenvobj(robj->obj,robj->matrix);
  427.             }    
  428.         }
  429.         robj = robj->next;
  430.           }
  431.         if(demo)
  432.         sleep(1);
  433.  
  434.         backface(1);
  435.         settexture(0);
  436.         blendfunction(BF_ZERO,BF_SC);
  437. #ifdef OLDWAY
  438.         blendfunction(BF_ZERO,BF_SA);
  439. #endif
  440.         wmpack(0x00ffffff);
  441.         robj = trendlist;
  442.         while(robj) {
  443.         tr = 255.0*robj->transc.x+0.49;    /* dim area */
  444.         tg = 255.0*robj->transc.y+0.49;
  445.         tb = 255.0*robj->transc.z+0.49;
  446.         c = (tb<<16)+(tg<<8)+(tr<<0);
  447.         cpack(c);
  448.         loadmatrix(robj->matrix);
  449.         drawsgiobj(robj->obj,DRAW_POINTS);
  450. #ifdef OLDWAY
  451.         tr = 255.0*robj->transc.x+0.49;    /* dim area */
  452.         tg = 255.0*robj->transc.y+0.49;
  453.         tb = 255.0*robj->transc.z+0.49;
  454.         loadmatrix(robj->matrix);
  455.         if(tr == tg  && tg == tb) {
  456.             wmpack(0x00ffffff);
  457.             cpack(tr<<24);
  458.             drawsgiobj(robj->obj,DRAW_POINTS);
  459.         } else {
  460.             wmpack(0x000000ff);
  461.             cpack(tr<<24);
  462.             drawsgiobj(robj->obj,DRAW_POINTS);
  463.             wmpack(0x0000ff00);
  464.             cpack(tg<<24);
  465.             drawsgiobj(robj->obj,DRAW_POINTS);
  466.             wmpack(0x00ff0000);
  467.             cpack(tb<<24);
  468.             drawsgiobj(robj->obj,DRAW_POINTS);
  469.         }
  470. #endif
  471.         robj = robj->next;
  472.         }
  473.         if(demo)
  474.         sleep(1);
  475.  
  476.         zwritemask(0x00ffffff);     /* get closest zee's */
  477.         backface(1);            
  478.         blendfunction(BF_ONE,BF_ZERO);
  479.         wmpack(0x00000000);
  480.         robj = trendlist;
  481.         while(robj) {
  482.         loadmatrix(robj->matrix);
  483.         drawsgiobj(robj->obj,DRAW_POINTS);
  484.         robj = robj->next;
  485.         }
  486.  
  487.         zwritemask(0x00000000);     /* add in specular on front */
  488.         backface(1);            
  489.         blendfunction(BF_ONE,BF_ONE);
  490.         wmpack(0x00ffffff);
  491.         robj = trendlist;
  492.         while(robj) {
  493.         if(robj->specmap) {
  494.             v.x = robj->specc.x*(1.0-robj->transc.x);
  495.             v.y = robj->specc.y*(1.0-robj->transc.y);
  496.             v.z = robj->specc.z*(1.0-robj->transc.z);
  497.             if(vsignif(&v)) {
  498.             tmc3f((float*)&v);
  499.             settexture(robj->specmap);
  500.             loadmatrix(robj->matrix);
  501.             drawenvobj(robj->obj,robj->matrix);
  502.             }        
  503.         }
  504.         robj = robj->next;
  505.         }
  506.  
  507.         zwritemask(0x00000000);     /* add in diffuse on front */
  508.         backface(1);            
  509.         blendfunction(BF_ONE,BF_ONE);
  510.         wmpack(0x00ffffff);
  511.         robj = trendlist;
  512.         while(robj) {
  513.         if(robj->isdiff) {
  514.             vdif.x = robj->diffc.x*(1.0-robj->transc.x);
  515.             vdif.y = robj->diffc.y*(1.0-robj->transc.y);
  516.             vdif.z = robj->diffc.z*(1.0-robj->transc.z);
  517.             if(vsignif(&v)) {
  518.             tmc3f((float*)&vdif);
  519.             settexture(robj->diffmap);
  520.             loadmatrix(robj->matrix);
  521.             if(robj->diffmap)
  522.                 drawsgiobj(robj->obj,DRAW_POINTS|DRAW_NORMALS|DRAW_UVS);
  523.             else
  524.                 drawsgiobj(robj->obj,DRAW_POINTS|DRAW_NORMALS);
  525.             }
  526.         }
  527.         robj = robj->next;
  528.         }
  529.  
  530.         if(demo)
  531.         sleep(1);
  532.         break;
  533.     }
  534.     popmatrix();
  535. }
  536.  
  537. static objidcolor(id)
  538. int id;
  539. {
  540.     long c;
  541.     int i, rbit, gbit, bbit;
  542.  
  543.     id++;
  544.     c = 0;
  545.     for(i=0; i<8; i++) {
  546.         rbit = (id>>((3*i)+0))&1;
  547.         gbit = (id>>((3*i)+1))&1;
  548.         bbit = (id>>((3*i)+2))&1;
  549.     c |= (rbit<<(7-i))+(gbit<<(15-i))+(bbit<<(23-i));
  550.     }
  551.     cpack(c);
  552. }
  553.  
  554. makearray(func,nx,ny,space)
  555. int (*func)();
  556. int nx, ny;
  557. float space;
  558. {
  559.     int x, y;
  560.     float tx, ty;
  561.  
  562.     for(y=0; y<ny; y++) {
  563.         for(x=0; x<nx; x++) {
  564.         tx = x-(nx-1)/2.0;
  565.         ty = y-(ny-1)/2.0;
  566.         pushmatrix();
  567.         translate(tx*space,0.0,ty*space);
  568.         func();
  569.         popmatrix();
  570.         }
  571.     }
  572. }
  573.  
  574. gfxinit()
  575. {
  576.     zbuffer(1);
  577.     subpixel(1);
  578.     RGBmode();
  579.     doublebuffer();
  580.     gconfig();
  581.     matinit();
  582.     cpack(0x808080);
  583.     clear();
  584.     swapbuffers();
  585. }
  586.  
  587. vsignif(v)
  588. vect *v;
  589. {
  590.     if(v->x>(1.0/255.0))
  591.     return 1;
  592.     if(v->y>(1.0/255.0))
  593.     return 1;
  594.     if(v->z>(1.0/255.0))
  595.     return 1;
  596.     return 0;
  597. }
  598.  
  599. /*
  600.  *    accbuff stuff follows
  601.  *
  602.  *
  603.  */
  604. static char accfile[256];
  605.  
  606. doaccbuf(drawfunc,filename)
  607. int (*drawfunc)();
  608. char *filename;
  609. {
  610.     FILE *lensf;
  611.     FILE *accf;
  612.     ACCPNTS *pixlpnts;
  613.     ACCPNTS *lenspnts;
  614.     int i, npasses;
  615.     float xpix, ypix, xshift, yshift;
  616.  
  617.     strcpy(accfile,filename);
  618.     pixlpnts = openpnts("/usr/people/paul/gfx/acc/pixl.pnts");
  619.     lenspnts = openpnts("/usr/people/paul/gfx/acc/lens.pnts");
  620.     npasses = numpnts(pixlpnts);
  621.     printf("npasses is %d\n",npasses);
  622.     myacsize(16);
  623.     gconfig();
  624.     myacbuf(AC_CLEAR,0.0);
  625.     tpercentdone(0.0);
  626.     for(i=0; i<npasses; i++) {
  627.     getaccpnt(pixlpnts,i,&xpix,&ypix);    
  628.     getaccpnt(lenspnts,i,&xshift,&yshift);    
  629.     xshift -= 0.5;
  630.     yshift -= 0.5;
  631.     accset(xpix,ypix,xshift,yshift);
  632.     drawfunc(i/(npasses-1.0));
  633.     myacbuf(AC_ACCUMULATE,ACCSCALE);
  634.     tpercentdone(100.0*i/(npasses-1));
  635. #ifdef USEGLACCBUF
  636.     myacbuf(AC_RETURN,1.0/(ACCSCALE*(i+1)));
  637.     swapbuffers();
  638. #endif
  639.     }
  640.     myacbuf(AC_RETURN,1.0/(ACCSCALE*npasses));
  641.     swapbuffers();
  642.     myacsize(0);
  643.     gconfig();
  644. }
  645.  
  646. static int accfirsted;
  647.  
  648. myacsize(nbits)
  649. int nbits;
  650. {
  651. #ifdef USEGLACCBUF    
  652.     acsize(nbits);
  653. #endif
  654. }
  655.  
  656. myacbuf(func,value)
  657. int func;
  658. float value;
  659. {
  660.     long xsize, ysize;
  661.  
  662. #ifdef USEGLACCBUF    
  663.     acbuf(func,value);
  664. #else
  665.     if(!accfirsted) {
  666.     getsize(&xsize,&ysize);
  667.     newacc(xsize,ysize);
  668.     accfirsted = 1;
  669.     }
  670.     switch(func) {
  671.     case AC_CLEAR:
  672.         clearacc();
  673.         break;
  674.     case AC_ACCUMULATE:
  675.         addtoacc();
  676.         break;
  677.     case AC_RETURN:
  678.         saveacc(accfile);
  679.         break;
  680.     }
  681. #endif
  682. }
  683.  
  684. /*
  685.  *    pspoly render follows . . .
  686.  *
  687.  */
  688. static FILE *tlfile;
  689. static float *psprojmat;
  690.  
  691. #define TRITOL     (0.000000001)
  692.  
  693. tocpack(v)
  694. float v[4];
  695. {
  696.     int r, g, b, a;
  697.     unsigned long c;
  698.  
  699.     r = 255.0*v[0];
  700.     g = 255.0*v[1];
  701.     b = 255.0*v[2];
  702.     a = 255.0*v[3];
  703.     c =  (a<<24) + (b<<16) + (g<<8) + (r<<0);
  704.     return c;
  705. }
  706.  
  707. static transtri;
  708.  
  709. static pstrifunc(p0,p1,p2)
  710. long *p0, *p1, *p2;
  711. {
  712.     vect tp0, tp1, tp2, n;
  713.     vect pj0, pj1, pj2, pn;
  714.     vect t, c0, c1, c2;
  715.     float a;
  716.     trilisttri tri;
  717.  
  718.     if(transtri)
  719.     a = 0.0;
  720.     else
  721.     a = 1.0;
  722.     xformvert4(psprojmat,p0+OFFSET_POINT,&tp0);
  723.     xformvert4(psprojmat,p1+OFFSET_POINT,&tp1);
  724.     xformvert4(psprojmat,p2+OFFSET_POINT,&tp2);
  725.     if(trinormal(&tp0,&tp1,&tp2,&n,TRITOL)) {
  726.     pj0.x = tp0.x/tp0.w;
  727.     pj0.y = tp0.y/tp0.w;
  728.     pj0.z = tp0.z/tp0.w;
  729.     pj1.x = tp1.x/tp1.w;
  730.     pj1.y = tp1.y/tp1.w;
  731.     pj1.z = tp1.z/tp1.w;
  732.     pj2.x = tp2.x/tp2.w;
  733.     pj2.y = tp2.y/tp2.w;
  734.     pj2.z = tp2.z/tp2.w;
  735.     tenv(p0+OFFSET_NORMAL,p0+OFFSET_POINT,&t);
  736.     fakettoc(&t,&c0);
  737.     tenv(p1+OFFSET_NORMAL,p1+OFFSET_POINT,&t);
  738.     fakettoc(&t,&c1);
  739.     tenv(p2+OFFSET_NORMAL,p2+OFFSET_POINT,&t);
  740.     fakettoc(&t,&c2);
  741.     c0.w = c1.w = c2.w = a;
  742.     tri.x0 = pj0.x;
  743.     tri.y0 = pj0.y;
  744.     tri.z0 = -pj0.z;
  745.     tri.c0 = tocpack(&c0);
  746.     tri.x1 = pj1.x;
  747.     tri.y1 = pj1.y;
  748.     tri.z1 = -pj1.z;
  749.     tri.c1 = tocpack(&c1);
  750.     tri.x2 = pj2.x;
  751.     tri.y2 = pj2.y;
  752.     tri.z2 = -pj2.z;
  753.     tri.c2 = tocpack(&c2);
  754.     fwrite(&tri,sizeof(trilisttri),1,tlfile);
  755.     }
  756. }
  757.  
  758. pspolyrender()
  759. {
  760.     rendobj *robj;
  761.     float projmat[4][4], psmat[4][4];
  762.     short magic;
  763.  
  764.     tlfile = fopen("/tmp/gscript.tl","w");
  765.     if(!tlfile) {
  766.     fprintf(stderr,"render: can't open trilist file\n");
  767.     return;
  768.     }
  769.     magic = TLMAGIC;
  770.     fwrite(&magic,sizeof(short),1,tlfile);
  771.     robj = orendlist;
  772.     mmode(MPROJECTION);
  773.     getmatrix(projmat);
  774.     mmode(MVIEWING);
  775.     transtri = 0;
  776.     while(robj) {
  777.     matrixmult(projmat,robj->matrix,psmat);
  778.     psprojmat = &psmat[0][0];
  779.     tenvmat(&robj->matrix[0][0]);
  780.     tmc3f((float*)&robj->specc);
  781.     settexture(robj->specmap);
  782.     applytotris(robj->obj,pstrifunc);
  783.     robj = robj->next;
  784.  
  785.     }
  786.     transtri = 1;
  787.     robj = trendlist;
  788.     while(robj) {
  789.     matrixmult(projmat,robj->matrix,psmat);
  790.     psprojmat = &psmat[0][0];
  791.     tenvmat(&robj->matrix[0][0]);
  792.     tmc3f((float*)&robj->specc);
  793.     settexture(robj->specmap);
  794.     applytotris(robj->obj,pstrifunc);
  795.     robj = robj->next;
  796.     }
  797.     fclose(tlfile);
  798. }
  799.